#include <stdio.h>

#include "defines.h"

extern char	*token, *prog;
extern char	*getlabel();
extern int	gettoken(), tokentype, tokenstat;

void	label_init();

struct label {			/* storage for the labels */
	char	name[LAB_LEN];	/* label name */
	char	*p;		/* points to place to go in source file */
};

struct label label[NUM_LAB];

/*
 * initlabels - find all labels
 */
void
initlabels(ltoken)
char	*ltoken;
{
	int	addr;
	char	*temp;

	label_init();			/* zero all labels */
	temp = prog;			/* save pointer to top of program */

	/* if the first token in the file is a label */
	tokentype = gettoken(ltoken);
	if (tokentype == NUMBER) {
		strcpy(label[0].name, ltoken);
		label[0].p = prog;
	}

	geteol();
	do {
		tokentype = gettoken(ltoken);
		if (tokentype == NUMBER) {
			addr = getnext_label(ltoken);
			if (addr == -1 || addr == -2) {
				if (addr == -1)
					b_error(5);
				else
					b_error(6);
			}
			strcpy(label[addr].name, ltoken);
			label[addr].p = prog;	/* current point in program */
		}
		/* if not on a blank line, find next line */
		if (tokenstat != EOL)
			geteol();
	} while (tokenstat != FINISHED);
	prog = temp;	/* restore to original */
}


/*
 * getnext_label - Return index of next free position in label array.
 *
 * returns:	-1 if the array is full.
 *		-2 when duplicate label is found.
 */
getnext_label(s)
char	*s;
{
	register int	t;

	for (t = 0; t < NUM_LAB; ++t) {
		if (label[t].name[0] == 0)
			return t;
		if (!strcmp(label[t].name, s))
			return (-2);	/* duplicate label */
	}
	return (-1);
}


/*
 * getlabel - find location of given label.
 *
 * returns:	null if label is not found
 * 		pointer to the position of the label
 */
char	*
getlabel(s)
char	*s;
{
	register int	t;

	for (t = 0; t < NUM_LAB; ++t)
		if (!strcmp(label[t].name, s))
			return (label[t].p);
	return NULL;	/* error condition */
}


/*
 * label_init - initialize the array that holds the labels.
 *
 * By convention, a null label name indicates that array 
 * position is unused.
 */
void
label_init()
{
	register int	t;

	for (t = 0; t < NUM_LAB; ++t)
		label[t].name[0] = NULL;
}


